package com.ruoyi.report_tg.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.BigDecimalUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.syrw.annotation.FIllBasicInfo;
import com.ruoyi.syrw.common.GaussianFunction;
import com.ruoyi.syrw.common.LineFunction;
import com.ruoyi.syrw.common.LineUtil;
import com.ruoyi.report_tg.domain.TdczbjlbeBaDetail;
import com.ruoyi.report_tg.domain.vo.GeneralCharDataVo;
import com.ruoyi.report_tg.domain.vo.TdczbjlbeBaDetailVo;
import com.ruoyi.report_tg.mapper.TdczbjlbeBaDetailMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.report_tg.domain.bo.TdczbjlbeBsInfoBo;
import com.ruoyi.report_tg.domain.vo.TdczbjlbeBsInfoVo;
import com.ruoyi.report_tg.domain.TdczbjlbeBsInfo;
import com.ruoyi.report_tg.mapper.TdczbjlbeBsInfoMapper;
import com.ruoyi.report_tg.service.ITdczbjlbeBsInfoService;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Collection;

/**
 * 土的承载比(CBR)记录二Service业务层处理
 *
 * @author zyb
 * @date 2024-05-24
 */
@RequiredArgsConstructor
@Service
@Transactional
public class TdczbjlbeBsInfoServiceImpl implements ITdczbjlbeBsInfoService {

    private final TdczbjlbeBsInfoMapper baseMapper;
    private final TdczbjlbeBaDetailMapper detailMapper;

    /**
     * 查询土的承载比(CBR)记录二
     */
    @Override
    @FIllBasicInfo
    public TdczbjlbeBsInfoVo queryById(Long excelId) {
        TdczbjlbeBsInfoVo tdczbjlbeBsInfoVo = baseMapper.selectVoById(excelId);
        // 查询detail
        List<TdczbjlbeBaDetailVo> baDetailVos = detailMapper.selectVoList(new LambdaQueryWrapper<TdczbjlbeBaDetail>()
            .eq(TdczbjlbeBaDetail::getExcelId, excelId)
            .orderByAsc(TdczbjlbeBaDetail::getRow)
            .orderByAsc(TdczbjlbeBaDetail::getCol));
        if (CollUtil.isNotEmpty(baDetailVos)) {
            tdczbjlbeBsInfoVo.setBaDetailVos(baDetailVos);
        }
        return compute(tdczbjlbeBsInfoVo);
    }

    /**
     * 查询土的承载比(CBR)记录二列表
     */
    @Override
    public TableDataInfo<TdczbjlbeBsInfoVo> queryPageList(TdczbjlbeBsInfoBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TdczbjlbeBsInfo> lqw = buildQueryWrapper(bo);
        Page<TdczbjlbeBsInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询土的承载比(CBR)记录二列表
     */
    @Override
    public List<TdczbjlbeBsInfoVo> queryList(TdczbjlbeBsInfoBo bo) {
        LambdaQueryWrapper<TdczbjlbeBsInfo> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<TdczbjlbeBsInfo> buildQueryWrapper(TdczbjlbeBsInfoBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TdczbjlbeBsInfo> lqw = Wrappers.lambdaQuery();
//        lqw.eq(bo.getTotalPage() != null, TdczbjlbeBsInfo::getTotalPage, bo.getTotalPage());
//        lqw.eq(bo.getPage() != null, TdczbjlbeBsInfo::getPage, bo.getPage());
//        lqw.eq(StringUtils.isNotBlank(bo.getJilbh()), TdczbjlbeBsInfo::getJilbh, bo.getJilbh());
//        lqw.eq(StringUtils.isNotBlank(bo.getJiancdwmc()), TdczbjlbeBsInfo::getJiancdwmc, bo.getJiancdwmc());
//        lqw.eq(StringUtils.isNotBlank(bo.getGongcbwyt()), TdczbjlbeBsInfo::getGongcbwyt, bo.getGongcbwyt());
//        lqw.eq(StringUtils.isNotBlank(bo.getYangpmc()), TdczbjlbeBsInfo::getYangpmc, bo.getYangpmc());
//        lqw.eq(StringUtils.isNotBlank(bo.getYangpbh()), TdczbjlbeBsInfo::getYangpbh, bo.getYangpbh());
//        lqw.eq(StringUtils.isNotBlank(bo.getYangpsl()), TdczbjlbeBsInfo::getYangpsl, bo.getYangpsl());
//        lqw.eq(StringUtils.isNotBlank(bo.getYangpzt()), TdczbjlbeBsInfo::getYangpzt, bo.getYangpzt());
//        lqw.eq(bo.getYangpsj() != null, TdczbjlbeBsInfo::getYangpsj, bo.getYangpsj());
//        lqw.eq(StringUtils.isNotBlank(bo.getShiyjcrq()), TdczbjlbeBsInfo::getShiyjcrq, bo.getShiyjcrq());
//        lqw.eq(StringUtils.isNotBlank(bo.getShiytjwd()), TdczbjlbeBsInfo::getShiytjwd, bo.getShiytjwd());
//        lqw.eq(StringUtils.isNotBlank(bo.getShiytjsd()), TdczbjlbeBsInfo::getShiytjsd, bo.getShiytjsd());
//        lqw.eq(StringUtils.isNotBlank(bo.getJiancyj()), TdczbjlbeBsInfo::getJiancyj, bo.getJiancyj());
//        lqw.eq(StringUtils.isNotBlank(bo.getPandyj()), TdczbjlbeBsInfo::getPandyj, bo.getPandyj());
//        lqw.eq(StringUtils.isNotBlank(bo.getZhuyyqsbmcjbh()), TdczbjlbeBsInfo::getZhuyyqsbmcjbh, bo.getZhuyyqsbmcjbh());
//        lqw.eq(StringUtils.isNotBlank(bo.getFujsm()), TdczbjlbeBsInfo::getFujsm, bo.getFujsm());
//        lqw.eq(bo.getZuidgmd() != null, TdczbjlbeBsInfo::getZuidgmd, bo.getZuidgmd());
//        lqw.eq(bo.getZuijhsl() != null, TdczbjlbeBsInfo::getZuijhsl, bo.getZuijhsl());
//        lqw.eq(bo.getGuanrgmj() != null, TdczbjlbeBsInfo::getGuanrgmj, bo.getGuanrgmj());
//        lqw.eq(StringUtils.isNotBlank(bo.getTongh1()), TdczbjlbeBsInfo::getTongh1, bo.getTongh1());
//        lqw.eq(StringUtils.isNotBlank(bo.getTongh2()), TdczbjlbeBsInfo::getTongh2, bo.getTongh2());
//        lqw.eq(StringUtils.isNotBlank(bo.getTongh3()), TdczbjlbeBsInfo::getTongh3, bo.getTongh3());
//        lqw.eq(bo.getMeicjs1() != null, TdczbjlbeBsInfo::getMeicjs1, bo.getMeicjs1());
//        lqw.eq(bo.getMeicjs2() != null, TdczbjlbeBsInfo::getMeicjs2, bo.getMeicjs2());
//        lqw.eq(bo.getMeicjs3() != null, TdczbjlbeBsInfo::getMeicjs3, bo.getMeicjs3());
//        lqw.eq(bo.getDanwyl2p5mm1() != null, TdczbjlbeBsInfo::getDanwyl2p5mm1, bo.getDanwyl2p5mm1());
//        lqw.eq(bo.getDanwyl2p5mm2() != null, TdczbjlbeBsInfo::getDanwyl2p5mm2, bo.getDanwyl2p5mm2());
//        lqw.eq(bo.getDanwyl2p5mm3() != null, TdczbjlbeBsInfo::getDanwyl2p5mm3, bo.getDanwyl2p5mm3());
//        lqw.eq(bo.getCbr2p5mm1() != null, TdczbjlbeBsInfo::getCbr2p5mm1, bo.getCbr2p5mm1());
//        lqw.eq(bo.getCbr2p5mm2() != null, TdczbjlbeBsInfo::getCbr2p5mm2, bo.getCbr2p5mm2());
//        lqw.eq(bo.getCbr2p5mm3() != null, TdczbjlbeBsInfo::getCbr2p5mm3, bo.getCbr2p5mm3());
//        lqw.eq(bo.getDanwyl5p0mm1() != null, TdczbjlbeBsInfo::getDanwyl5p0mm1, bo.getDanwyl5p0mm1());
//        lqw.eq(bo.getDanwyl5p0mm2() != null, TdczbjlbeBsInfo::getDanwyl5p0mm2, bo.getDanwyl5p0mm2());
//        lqw.eq(bo.getDanwyl5p0mm3() != null, TdczbjlbeBsInfo::getDanwyl5p0mm3, bo.getDanwyl5p0mm3());
//        lqw.eq(bo.getCbr5p0mm1() != null, TdczbjlbeBsInfo::getCbr5p0mm1, bo.getCbr5p0mm1());
//        lqw.eq(bo.getCbr5p0mm2() != null, TdczbjlbeBsInfo::getCbr5p0mm2, bo.getCbr5p0mm2());
//        lqw.eq(bo.getCbr5p0mm3() != null, TdczbjlbeBsInfo::getCbr5p0mm3, bo.getCbr5p0mm3());
//        lqw.eq(bo.getCbrpjz2p5() != null, TdczbjlbeBsInfo::getCbrpjz2p5, bo.getCbrpjz2p5());
//        lqw.eq(bo.getCbrpjz5p0() != null, TdczbjlbeBsInfo::getCbrpjz5p0, bo.getCbrpjz5p0());
        return lqw;
    }

    /**
     * 新增土的承载比(CBR)记录二
     */
    @Override
    @DSTransactional
    public Boolean insertByBo(TdczbjlbeBsInfoBo bo) {
        TdczbjlbeBsInfo add = BeanUtil.toBean(bo, TdczbjlbeBsInfo.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setExcelId(add.getExcelId());
            // 新增详细 3 * 12
            ArrayList<TdczbjlbeBaDetail> details = new ArrayList<>(36);
            for (long i = 0; i < 12L; i++) {
                for (long l = 0; l < 3L; l++) {
                    details.add(new TdczbjlbeBaDetail(add.getExcelId(), i, l));
                }
            }
            detailMapper.insertBatch(details, 36);
        }
        return flag;
    }

    /**
     * 修改土的承载比(CBR)记录二
     */
    @Override
    @DSTransactional
    public Boolean updateByBo(TdczbjlbeBsInfoBo bo) {
        TdczbjlbeBsInfo update = BeanUtil.toBean(bo, TdczbjlbeBsInfo.class);
        validEntityBeforeSave(update);
        boolean flag = baseMapper.updateById(update) > 0;
        if (flag) {
            detailMapper.updateBatchById(BeanUtil.copyToList(bo.getBaDetailVos(), TdczbjlbeBaDetail.class));
        }
        return flag;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TdczbjlbeBsInfo entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除土的承载比(CBR)记录二
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public TdczbjlbeBsInfoVo compute(TdczbjlbeBsInfoVo vo) {
        // 1. 参数判断 如果有任何一个为空,则 直接原样返回
        List<TdczbjlbeBaDetailVo> detailVos = vo.getBaDetailVos();
        if (CollUtil.isEmpty(detailVos)) {
            return vo;
        }
        // 1.2 分3个图
        for (int l = 0; l < 3; l++) {
            // 1.3 非空判断
            for (TdczbjlbeBaDetailVo detailVo : detailVos) {
                if (detailVo.getCol().intValue() == l && !StrUtil.isAllNotEmpty(detailVo.getDanwyl(), detailVo.getGuanrl())) {
                    return vo;
                }
            }
            double[][] data = new double[12][2];
            double[][] data2p5 = new double[2][2];
            double[][] data5p0 = new double[2][2];
            try {
                for (int i = 0; i < 12; i++) {
                    String danwylStr = vo.getDetailVo(i, l).getDanwyl();
                    String guanrlStr = vo.getDetailVo(i, l).getGuanrl();
                    data[i][0] = Double.parseDouble(danwylStr);
                    data[i][1] = Double.parseDouble(guanrlStr);
                }
                // 2 计算
                data2p5[0][0] = Double.parseDouble(vo.getDetailVo(5, l).getDanwyl());
                data2p5[0][1] = Double.parseDouble(vo.getDetailVo(5, l).getGuanrl());
                data2p5[1][0] = Double.parseDouble(vo.getDetailVo(6, l).getDanwyl());
                data2p5[1][1] = Double.parseDouble(vo.getDetailVo(6, l).getGuanrl());

                data5p0[0][0] = Double.parseDouble(vo.getDetailVo(10, l).getDanwyl());
                data5p0[0][1] = Double.parseDouble(vo.getDetailVo(10, l).getGuanrl());
                data5p0[1][0] = Double.parseDouble(vo.getDetailVo(11, l).getDanwyl());
                data5p0[1][1] = Double.parseDouble(vo.getDetailVo(11, l).getGuanrl());
            } catch (NumberFormatException e) {
                throw new ServiceException("土的承载比二计算时，解析数值错误，请检查填入的数据的合法性，或者截图联系管理员处理");
            }
            LineFunction generalLine2p5 = LineUtil.getGeneralLine(data2p5);
            LineFunction generalLine5p0 = LineUtil.getGeneralLine(data5p0);
            vo.setComputValue(l, generalLine2p5, generalLine5p0);
            // 3 画图的数据
            List<GeneralCharDataVo> charData = new ArrayList<>(20);
            // 3.1 参与画线 展示 不突出辅助线
            for (double[] datum : data) {
                charData.add(new GeneralCharDataVo(datum, "110"));
            }
            // 3.2 不参与画线 展示 突出辅助线
            charData.add(new GeneralCharDataVo(new double[]{Double.parseDouble(vo.getCompuValue(l)[0]), 2.5d}, "011"));
            charData.add(new GeneralCharDataVo(new double[]{Double.parseDouble(vo.getCompuValue(l)[1]), 5.0d}, "011"));
            vo.setChart(l, charData);
        }
        if (!StrUtil.isAllNotEmpty(vo.getCbr2p5mm1(), vo.getCbr2p5mm2(), vo.getCbr2p5mm3())) {
            return vo;
        }
        try {
            vo.setCbrpjz2p5(BigDecimalUtil.defaultValue(((Double.parseDouble(vo.getCbr2p5mm1()) + Double.parseDouble(vo.getCbr2p5mm2())
                + Double.parseDouble(vo.getCbr2p5mm3())) / 3), 1).toPlainString());
        } catch (NumberFormatException e) {
            throw new ServiceException("土的承载比二计算时，解析数值错误，请检查填入的数据的合法性，或者截图联系管理员处理");
        }

        return vo;
    }

    private List<GeneralCharDataVo> generateData(GaussianFunction gaussianFuncLine, double start, double end) {
        List<GeneralCharDataVo> result = new ArrayList<>(600);
        for (double i = 10.; i <= end + 50d; i += 30) {
            result.add(new GeneralCharDataVo(new double[]{BigDecimalUtil.defaultValue(i, 2).doubleValue(),
                gaussianFuncLine.getY(i)}, "100"));
        }
        return result;
    }

}
